//
//  FunctionClassController.swift
//  Algorithm
//
//  Created by 陈志强 on 2021/10/12.
//

import UIKit


infix operator >>> : AdditionPrecedence
func >>>(_ f1:@escaping (Int)->Int,_ f2:@escaping (Int)->Int) -> (Int) -> Int{
//    return { f2(f1($0)) }
    
    return{
        let abc = f1($0)
        return { abc }()
    }
}

class FunctionClassController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = UIColor.white

        let btn = UIButton(frame: CGRect(x: 20, y: 200, width: 100, height: 100))
        btn.addTarget(self, action: #selector(AnimalTest), for: .touchUpInside)
        btn.backgroundColor = UIColor.yellow
        self.view.addSubview(btn)
    }
    
    @objc func AnimalTest(){
        let dog = Dog()
        let bird = Bird()
        
        var homeApi = MainApi.Home.homeInfo
        let prodAPi = ProductApi.Product.productList
        homeApi.method = "post"
        
        loadAPI(apiItem: homeApi)
        loadAPI(apiItem: prodAPi)
        
        animalTest(animal: dog)
        animalTest(animal: bird)
    }
    
    func loadAPI(apiItem: ApiItemProtocol){
        ATLog("apiitem:\(apiItem.description) apiURL:\(apiItem.loadRequestURL())")
    }
    
    func animalTest(animal: AnimalProtocol){
        animal.run()
    }
    
    func searchHalf(){
        let index = HalfSearch().searchNumber(goalNumber: 16)
        ATLog("index= \(String(describing: index))")
    }
    
    func stackOverflowAnswer(img: UIImage) {
      if let data = img.pngData() {
          print("There were \(data.count) bytes")
          let bcf = ByteCountFormatter()
          bcf.allowedUnits = [.useMB] // optional: restricts the units to MB only
          bcf.countStyle = .file
          let string = bcf.string(fromByteCount: Int64(data.count))
          print("formatted result: \(string)")
      }
    }
    
    func loadCustomData(){
        //((((10+2)*6)/3)%10)-2  72/3
        let num = 2
        
        let fn1 = plusFunction(num: 10)(num)
        let fn2 = multiply(num: 6)(fn1)
        let fn3 = divide(num: 3)(fn2)
        let fn4 = mod(num: 10)(fn3)
        let fn5 = minusFunction(num: 2)(fn4)
        
        ATLog("result:\(fn5)")
        
        let fn6 = minusFunction(num: 2)(mod(num: 10)(divide(num: 3)(multiply(num:6)(plusFunction(num: 10)(num)))))
        
        ATLog("resultA:\(fn6)")
    }
    
    func loadCustomOptimizeData(){
        //((((10+2)*6)/3)%10)-2  72/3
        let num = 2
        let fn = plusFunction(num: 10) >>> multiply(num: 6) >>> divide(num: 3) >>> mod(num: 10) >>> minusFunction(num: 2)
        let result = fn(num)
        ATLog("resultB:\(result)")
    }
}

extension FunctionClassController{
    func plusFunction(num: Int) -> (Int)->Int {
        return {$0 + num}
    }
    
    func minusFunction(num: Int) -> (Int) -> Int{
        return {$0-num}
    }
    
    func multiply(num: Int) -> (Int) -> Int{
        return {num * $0}
    }
    
    func divide(num: Int) -> (Int) -> Int{
        return { $0/num }
    }
    
    func mod(num: Int)-> (Int) -> Int{
        return { $0%num }
    }
}
